###############################################################################
#
# file: EditPlayerDialog.py
# author: Victor Bos
# 
# Copyright 2007--2011 Victor Bos
#
# This file is part of GREATOR.
#
#    GREATOR is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    GREATOR is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with GREATOR.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
import StringIO

import ScrolledText
import Tkinter
import Tkconstants

import io
import Player

FG_BORDER_WIDTH=5

CANCEL = 0
DELETED = 1
CHANGED = 2

class EditPlayerDialog(Tkinter.Toplevel):

    init_filename = ""

    def __init__(self, master=None, **kw):
        self.process_options(kw)
        Tkinter.Toplevel.__init__(self, master, kw)
        self.protocol('WM_DELETE_WINDOW', self.cancel_pressed)
        self.title(self.windowtitle)

        lframe = Tkinter.LabelFrame(
            self, 
            text=self.message)
        lframe.pack(side = Tkinter.TOP, fill=Tkinter.BOTH, expand=1)

        self.player = None
        self.player_name = Tkinter.StringVar()

        f1 = self.create_main_frame(lframe)
        if f1 is not None:
            f1.pack(side = Tkinter.TOP, expand=1, fill=Tkinter.BOTH, padx=10, pady=10)

        f2 = self.create_ok_cancel_buttons()
        f2.pack(
            side = Tkinter.TOP, 
            anchor = Tkinter.SW, 
            fill = Tkinter.X, 
            expand=1)

        self.result = CANCEL
        self.center_on_master(master)

    def clear_attr_text(self):
        if self.attr_text is not None:
            self.attr_text.delete("1.0",Tkinter.END)

    def append_attr_text(self, s):
        self.attr_text.insert(Tkinter.END, s)

    def set_player(self, player):
        self.player = player
        self.player_name.set(player.name)
        self.clear_attr_text()
        self.append_attr_text(self.get_attr_str())

    def create_main_frame(self, lframe):
        f = Tkinter.Frame(lframe)
        
        nl = Tkinter.Label(f, text="Name")
        nl.grid(row=0, column=0, sticky="ew")
 
        self.name_entry = Tkinter.Entry(f, textvariable=self.player_name)
        self.name_entry.grid(
            row = 0,
            column = 1,
            sticky = "ew")
        
        self.attr_text = ScrolledText.ScrolledText(
            f,
            bd=FG_BORDER_WIDTH,
            width=1,
            height=8,
            background="ghostwhite")
        self.attr_text.grid(
            row = 1,
            column = 0,
            columnspan = 2,
            sticky = "nesw")

        self.attr_text.bind(
            "<Leave>",
            lambda e: self.update_attrs())

        f.columnconfigure(1, weight=1)
        f.rowconfigure(1, weight=1)

        return f
    
    def update_attrs(self):
        self.buffer = []
        self.attr_text.dump(
            "1.0",
            Tkinter.END,
            command=self.filter_text,
            text=True)
        attrs_str = ("".join(self.buffer)).strip()
        attrs = io.read_attrs(attrs_str)
        self.set_player_attrs(attrs)

    def set_player_attrs(self, attrs):
        if self.player is not None:
            self.player.attrs = attrs
            self.result = CHANGED

    def filter_text(self, k, v, i):
        self.buffer.append(v)

    def get_attr_str(self, spc=""):
        s = StringIO.StringIO()
        io.write_attrs(self.player.attrs, s, spc)
        return s.getvalue()
                
    def create_ok_cancel_buttons(self):
        f = Tkinter.Frame(self)

        self.delete_button = Tkinter.Button(
            f,
            text="Delete",
            command=self.delete_pressed)
        self.delete_button.pack(side=Tkinter.LEFT)

        Tkinter.Label(f).pack(side=Tkinter.LEFT, expand=1)

        self.ok_button = Tkinter.Button(
            f,
            text="Ok",
            command=self.ok_pressed)
        self.ok_button.pack(side=Tkinter.LEFT)

        self.cancel_button = Tkinter.Button(
            f,
            text="Cancel",
            command=self.cancel_pressed)
        self.cancel_button.pack(side=Tkinter.LEFT)
        return f
    
    def center_on_master(self, master):
        if master is not None:
            x = (master.winfo_rootx() +
                 ((master.winfo_width() - self.winfo_reqwidth()) / 2.0))
            y = (master.winfo_rooty() +
                 ((master.winfo_height() - self.winfo_reqheight()) / 2.0))
            self.geometry("+%d+%d" % (x,y))
        
    def process_options(self, kw):
        self.set_option("message", kw, "Edit player")
        self.set_option("windowtitle", kw, "Player editor")
        
    def set_option(self, name, user_values, default):
        if name in user_values:
            setattr(self, name, user_values[name])
            del user_values[name]
        else:
            setattr(self, name, default)

    def delete_pressed(self):
        self.result = DELETED
        self.quit()

    def ok_pressed(self):
        if ((self.player is not None) and 
            (self.player_name.get() != self.player.name)):
            self.player.name = self.player_name.get()
            self.result = CHANGED
        self.quit()

    def get_player_name(self):
        return self.player_name.get()

    def cancel_pressed(self):
        self.result = CANCEL
        self.quit()

    def go(self):
        self.wait_visibility() # window needs to be visible for the grab
        self.grab_set()
        self.mainloop()
        return self.result
